#ifndef PBVP_EDGE_CACHE_H
#define PBVP_EDGE_CACHE_H

#include <algorithm>
#include <map>

namespace PBVP {
	/// Pair of end points of an edge
	/**
	 * The edge endpoints are ordered such that their Ids p1 < p2
	 */
	class EdgeEndPoints{
	public:
		/// End points p1 and p2 ( p1 < p2 )
		int p1, p2;

		/// Default Constructor
		EdgeEndPoints(int v1, int v2) {
			p1 = std::min(v1, v2);
			p2 = std::max(v1, v2);
		}

		friend bool operator < (const EdgeEndPoints& edge1, const EdgeEndPoints& edge2) {
			if(edge1.p1 < edge2.p1) return true;
			else if(edge1.p1 > edge2.p1) return false;
			else {
				// here edge1.p1 == edge2.p1
				if(edge1.p2 < edge2.p2) return true;
			}
			return false;
		}
	};

	///
	struct eqEdge {
		bool operator () (const EdgeEndPoints& edge1, const EdgeEndPoints& edge2) const
		{
			// the order of p1 and p2 shouldn't matter
			if(edge1.p1 == edge2.p1 && edge1.p2 == edge2.p2) return true;
			if(edge1.p1 == edge2.p2 && edge1.p2 == edge2.p1) return true;
			return false;
		}
	};

	/// Edge Cache
	/** 
	* cache Index is the class EdgeEndPoints and cache value is vertex id
	*/
	class EdgeCache{
	public:
		/// Default Contructor
		EdgeCache() {
			count = 0;
		}

		/// Try to find the index of an EdgeEndPoint in the cache.
		/** 
		*
		* @return int: -1 if the edge is not found
		*/
		int find(const EdgeEndPoints& edge);

		/// Insert an EdgeEndPoint into the cache.
		/**
		* Insert it and return the index.
		*/
		int insert(const EdgeEndPoints& edge);

	private:

		std::map<EdgeEndPoints, int> m_EdgeHash;
		std::map<EdgeEndPoints, int>::iterator m_EdgeIterator;

		int count;
	};
}

#endif